package com.tbit.uqbike.service.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.annos.EncapsulateMap;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.pojo.dto.PackageDelayDTO;
import com.tbit.uqbike.object.pojo.dto.RideCardUserDelayDTO;
import com.tbit.uqbike.object.pojo.vo.GiveRideCardVo;
import com.tbit.uqbike.object.pojo.vo.RideCardUserVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.value.UserRcDetail;
import com.tbit.uqbike.service.business.RideCardService;
import com.tbit.uqbike.webmanager.dao.capital.RefundLogDao;
import com.tbit.uqbike.webmanager.dao.core.AccountDao;
import com.tbit.uqbike.webmanager.dao.core.RideCardDao;
import com.tbit.uqbike.webmanager.dao.core.UserDao;
import com.tbit.uqbike.webmanager.dao.log.RideCardUserExtendLogDao;
import com.tbit.uqbike.webmanager.dao.log.RideCardUserExtendLogDetailDao;
import com.tbit.uqbike.webmanager.dao.stat.RideCardOrderDayStaDao;
import com.tbit.uqbike.webmanager.util.StringUtil;
import com.tbit.uqbike.webmanager.util.adaPay.AdaPayUtil;
import com.tbit.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 骑行会员
 *
 * @author Leon
 * 2019年9月24日 下午4:05:36
 */
@Slf4j
@Service("rideCardService")
public class RideCardServiceImpl implements RideCardService {

    @Autowired
    private RideCardDao rideCardDao;
    @Autowired
    private RefundLogDao refundLogDao;
    @Autowired
    private RideCardOrderDayStaDao rideCardOrderDayStaDao;
    @Autowired
    private RideCardUserExtendLogDao rideCardUserExtendLogDao;
    @Autowired
    private RideCardUserExtendLogDetailDao rideCardUserExtendLogDetailDao;
    @Resource
    private AccountDao accountDao;
    @Resource
    private UserDao usersDao;

    @Override
    public List<RideCard> queryPage(Integer accountId, Integer feeId, Integer pageNO, Integer rowCount) {
        Map<String, Object> map = new HashMap<>();
        map.put("feeId", feeId);
        map.put("accountId", accountId);
        map.put("page", (pageNO - 1) * rowCount);
        map.put("rowCount", rowCount);
        List<RideCard> rideCards = rideCardDao.queryPage(map);
        for (RideCard rideCard : rideCards) {
            if (Objects.isNull(rideCard.getVaildTime())) {
                continue;
            }
            List<RideCardVaild> vaildList = new ArrayList<>();
            for (String s : rideCard.getVaildTime().split(";")) {
                String[] split = s.split("-");
                RideCardVaild rideCardVaild = new RideCardVaild();
                rideCardVaild.setStartTime(split[0]);
                rideCardVaild.setEndTime(split[1]);
                vaildList.add(rideCardVaild);
            }
            rideCard.setRideCardVailds(vaildList);
        }
        return rideCards;
    }

    @Override
    public Integer queryCount(Integer accountId, Integer feeId) {
        Map<String, Object> map = new HashMap<>();
        map.put("feeId", feeId);
        map.put("accountId", accountId);
        return rideCardDao.queryCount(map);
    }

    @Override
    public void insert(RideCard rideCard) {
        if (rideCardDao.getCardByName(rideCard) > 0) {
            throw new BaseException("骑行卡名称重复:" + rideCard.getName());
        }
        if (rideCardDao.selectCount(rideCard.getAccountId()) >= 200) {
            throw new BaseException("骑行卡数量已达上限");
        }
        updateHeadSort(rideCard.getAccountId());
        rideCard.setCreateTime(new Date());
        rideCardDao.insert(rideCard);
    }

    /**
     * 查询骑行卡模板
     *
     * @param accountId 品牌id
     * @param pageNO    页数
     * @param pageCount 条数
     * @return result
     */
    @Override
    public Result<PageResult<RideCard>> queryTemplate(Integer accountId, Integer pageNO, Integer pageCount) {
        PageInfo<RideCard> pageInfo;
        //校验是否需要分页
        if (Objects.isNull(pageNO) || Objects.isNull(pageCount)) {
            List<RideCard> rideCardList = rideCardDao.queryTemplate(accountId);
            pageInfo = new PageInfo<>();
            pageInfo.setList(rideCardList);
        } else {
            pageInfo = PageHelper.startPage(pageNO, pageCount).doSelectPageInfo(() -> rideCardDao.queryTemplate(accountId));
        }
        for (RideCard rideCard : pageInfo.getList()) {
            if (Objects.isNull(rideCard.getVaildTime())) {
                continue;
            }
            List<RideCardVaild> vaildList = new ArrayList<>();
            for (String s : rideCard.getVaildTime().split(";")) {
                String[] split = s.split("-");
                RideCardVaild rideCardVaild = new RideCardVaild();
                rideCardVaild.setStartTime(split[0]);
                rideCardVaild.setEndTime(split[1]);
                vaildList.add(rideCardVaild);
            }
            rideCard.setRideCardVailds(vaildList);
        }
        PageResult<RideCard> pageResult = PageResult.convertPage(pageInfo, RideCard.class);
        return Result.success(pageResult);
    }

    /**
     * 修改骑行卡模板
     *
     * @param rideCard rideCard
     * @return result
     */
    @Override
    public Result<Object> updateTemplate(RideCard rideCard) {
        rideCardDao.deleteTemplateByName(rideCard);
        addRideCardTemplate(rideCard);
        return Result.success();
    }

    /**
     * 修改排序
     *
     * @param rideCard rideCard
     * @return result
     */
    @Override
    public Result<Object> updateSort(RideCard rideCard) {
        if (rideCard.getSort() == rideCard.getNewSort()) {
            return Result.success();
        }
        if (rideCardDao.selectSort(rideCard.getNewSort(), rideCard.getAccountId()) == 0) {
            //拒绝修改
            return Result.error("仅允许修改已存在的排序");
        } else {
            //先把原来的排序修改为null
            RideCard rideCard1 = new RideCard();
            rideCard1.setRideCardId(rideCard.getRideCardId());
            rideCardDao.updateSort(rideCard1);
            rideCardDao.updateOtherSort(rideCard.getAccountId(), rideCard.getSort(), rideCard.getNewSort());
            rideCardDao.updateSort(rideCard);
        }
        return Result.success();
    }

    /**
     * 新增骑行卡模板
     *
     * @param rideCard rideCard
     */
    @Override
    public Result<Object> addRideCardTemplate(RideCard rideCard) {
        if (rideCardDao.getByName(rideCard) > 0) {
            return Result.success(false);
        }
        rideCard.setCreateTime(new Date());
        //有效时段解析成startTime-endTime;
        StringBuilder vaildTime = new StringBuilder();
        if (rideCard.getRideCardVailds() != null) {
            for (RideCardVaild rideCardVaild : rideCard.getRideCardVailds()) {
                vaildTime.append(rideCardVaild.getStartTime()).append("-").append(rideCardVaild.getEndTime()).append(";");
            }
        }
        rideCardDao.addRideCardTemplate(rideCard);
        return Result.success(true);
    }

    /**
     * 删除骑行卡模板
     *
     * @param rideCardId 骑行卡模板id
     * @return result
     */
    @Override
    public Result<Object> deleteTemplate(Integer rideCardId) {
        rideCardDao.deleteTemplate(rideCardId);
        return Result.success();
    }


    @Override
    public void edit(RideCard rideCard) {
        if (rideCardDao.getCardByName(rideCard) > 1) {
            throw new BaseException("骑行卡名称重复:" + rideCard.getName());
        }
        rideCardDao.edit(rideCard);
    }

    @Override
    public RideCard getById(Integer rideCardId) {
        return rideCardDao.getById(rideCardId);
    }

    @Override
    public void editEnable(Integer rideCardId, Integer accountId) {
        RideCard rideCardDB = getById(rideCardId);
        if (rideCardDB == null) {
            throw new BaseException(SystemCodeEnum.RIDECARD_NOT_EXIST);
        }
        rideCardDao.editEnable(rideCardId);
        //置为失效后，后续骑行卡排序往前移
        RideCard rideCard = rideCardDao.getById(rideCardId);
        if (Objects.nonNull(rideCard)) {
            rideCardDao.updateMoveForword(accountId, rideCard.getSort());
        }
    }

    @Override
    public List<UserMember> userRideCardPage(Integer userId, Integer rowCount, Integer pageNO) {
        Map<String, Object> params = new HashMap<>(8);
        params.put("userId", userId);
        params.put("rowCount", rowCount);
        params.put("page", (pageNO - 1) * rowCount);
        List<UserMember> userMembers = rideCardDao.userRideCardPage(params);
        //骑行卡置为失效
        userMembers.forEach(userMember -> {
            if (new Date().compareTo(DateTimeUtil.StringToDateTime(userMember.getExpireTime() + " 23:59:59")) > 0 && Objects.equals(userMember.getUserType(), 0)) {
                userMember.setIsValid(0);
                rideCardDao.updateValid(userMember);
            }
            if (userMember.whetherDailyCardAndResetCurrentNum()) {
                rideCardDao.updateCurrentNumByOrderNo(userMember.getOrderNO(), 0);
            }
        });
        return userMembers;
    }

    @Override
    public Integer userRideCardCount(Integer userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        return rideCardDao.userRideCardCount(params);
    }

    @Override
    public Integer getMoneyByTime(List<Integer> accountIds, String startTime, String endTime, Integer type) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountIds", StringUtil.getListString(accountIds));
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        params.put("type", type);
        return rideCardDao.getMoneyByTime(params);
    }

    @Override
    public List<StatPark> statByType(List<Integer> accountIds, String startTime, String endTime,
                                     Integer type) {
        Date now = new Date();
        long nowTime = now.getTime();
        String ymd = DateTimeUtil.formatDateYMD(now);
        String time = ymd + " 00:00:00";
        long morningStartTime = DateTimeUtil.StringToDateTime(time).getTime();
        time = ymd + " 03:00:00";
        long nightStartTime = DateTimeUtil.StringToDateTime(time).getTime();
        List<StatPark> statParks = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        params.put("accountIds", StringUtil.getListString(accountIds));
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        params.put("type", type);
        Map<String, StatPark> stat = new HashMap<>();
        List<String> daysStr = DateTimeUtil.findDaysStr(DateTimeUtil.formatDateYMD(DateTimeUtil.StringToDateTime(startTime)), DateTimeUtil.formatDateYMD(DateTimeUtil.StringToDateTime(endTime)));
        if (type == 0) {
            List<StatPark> statParks1 = rideCardOrderDayStaDao.statByType(params);
            for (StatPark statPark : statParks1) {
                stat.put(statPark.getName(), statPark);
            }
            daysStr.forEach(day -> {
                Date start = DateTimeUtil.getYesterdayHHMMSS(day, -1);
                Date end = DateTimeUtil.getYesterdayHHMMSS(day, 0);
                params.put("startTime", start);
                params.put("endTime", end);
                if (DateTimeUtil.formatDateYMD(end).equals(DateTimeUtil.getNowTimeYMD())) {
                    statParks.add(rideCardDao.statByType(params).get(0));
                } else if (nowTime >= morningStartTime && nowTime < nightStartTime && day.equals(DateTimeUtil.getYesterday())) {
                    /**兼容0-3点前一日订单未统计*/
                    statParks.add(rideCardDao.statByType(params).get(0));
                } else {
                    if (stat.containsKey(day)) {
                        statParks.add(stat.get(day));
                    } else {
                        statParks.add(new StatPark(0, 0, day));
                    }
                }
            });
            return statParks;
        }
        return rideCardDao.statByType(params);
    }

    @Override
    public List<UserRcDetail> getRideCardPage(Integer accountId, Integer type, Long startTime,
                                              Long endTime, Integer pageNO, Integer rowCount) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        params.put("page", (pageNO - 1) * rowCount);
        params.put("rowCount", rowCount);
        return rideCardDao.getRideCardPage(params);
    }

    @Override
    public Integer getRideCardCount(Integer accountId, Integer type, Long startTime, Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        return rideCardDao.getRideCardCount(params);
    }

    @Override
    public List<UserRcDetail> export(Integer accountId, Integer type, Long startTime,
                                     Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        return rideCardDao.export(params);
    }

    @Override
    public MoneyData getTotalMoney(Integer accountId, Integer type, Long startTime, Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        return rideCardDao.getTotalMoney(params);
    }

    @Override
    @EncapsulateMap(name = "rideCardCountByType")
    public List<Map<String, Object>> rideCardCountByType(Map<String, Object> params, Integer accountId, Integer type, Long startTime, Long endTime) {
        return rideCardDao.selectCountByType(params);
    }

    @Override
    @EncapsulateMap(name = "ridecard")
    public void EdituserRideCard(Map<String, Object> params, Integer userId, Integer rideCardId, Integer type, String orderNO, Integer useCount, Integer maxRide) {
        rideCardDao.updateuserRideCard(params);
    }

    @Override
    public UserMember getByOrderNO(String orderNO) {
        return rideCardDao.getByOrderNO(orderNO);
    }

    @Override
    public Result<String> rideCardUserDelay(RideCardUserDelayDTO delayDTO) {
        final Integer accountId = delayDTO.getAccountId();
        final LoginInfo loginInfo = delayDTO.getLoginInfo();
        final Integer delayDays = delayDTO.getDelayDays();
        final Long stopStartTime = delayDTO.getStopStartTime();
        final Long stopEndTime = delayDTO.getStopEndTime();
        if (stopStartTime >= stopEndTime) {
            return Result.error("开始时间不能晚于结束时间");
        }
        //1.选取套餐骑行卡
        List<RideCardUserVO> cards = rideCardDao.selectRideCardUserToDelay(accountId, new Date(stopStartTime), new Date(stopEndTime));
        if (cards.isEmpty()) {
            return Result.error("运营区域内无可延长的骑行套餐");
        }

        Map<String, List<RideCardUserVO>> mapList = cards.stream().collect(Collectors.groupingBy(a -> a.getUserId() + "_" + a.getAccountId()));

        cards = mapList.entrySet().stream()
                .filter(x -> {
                    //过略存在已生效的骑行套餐用户
                    String[] keyArr = x.getKey().split("_");
                    Map<String, Object> queryMap = new HashMap<>(8);
                    queryMap.put("accountId", keyArr[1]);
                    queryMap.put("userId", keyArr[0]);
                    queryMap.put("valid", 1);
                    RideCardUserVO enableRideCard = rideCardDao.queryValidUserRideCard(queryMap);
                    if (enableRideCard == null) {
                        return true;
                    }
                    return x.getValue().stream().anyMatch(val -> Objects.equals(val.getOrderNO(), enableRideCard.getOrderNO()));
                })
                .peek(x -> {
                    //过滤已退款的骑行卡
                    List<RideCardUserVO> canExtendLog = x.getValue().stream().filter(val -> {
                        List<RefundLog> refundLogs = refundLogDao.selectList(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getMerchantNO, val.getOrderNO()));
                        return CollectionUtils.isEmpty(refundLogs);
                    }).collect(Collectors.toList());
                    x.setValue(canExtendLog);
                })
                .map(x -> {
                    //找出需要延期的张骑行卡  1.有效  2.剩余次数最多
                    RideCardUserVO rideCardUserVO = x.getValue().stream().filter(RideCardUser::getIsValid).findFirst().orElse(null);
                    if (rideCardUserVO != null) {
                        return rideCardUserVO;
                    }
                    return x.getValue().stream().filter(val -> val.getMaxRide() - val.getUseCount() > 0)
                            .max(Comparator.comparing(val -> val.getMaxRide() - val.getUseCount()))
                            .orElse(null);
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());


        //插入主日志
        RideCardUserExtendLog mainLog = new RideCardUserExtendLog(accountId, loginInfo.getAccountUserId(),
                loginInfo.getPhone(), loginInfo.getName(), cards.size(), delayDays, delayDTO.getRemark());
        rideCardUserExtendLogDao.insert(mainLog);
        //2.修改套餐到期时间
        for (RideCardUserVO card : cards) {
            RideCardUserExtendLogDetail detailLog = new RideCardUserExtendLogDetail()
                    .setLogId(mainLog.getId())
                    .setOrderNo(card.getOrderNO())
                    .setUserId(card.getUserId())
                    .setUserPhone(card.getPhone())
                    .setCardId(card.getRideCardId())
                    .setCardName(card.getCardName())
                    .setBeforeEndDate(card.getEndDate());
            card.extendExpirationTime(delayDays);
            rideCardDao.updateEndTimeByOrderNo(card);
            detailLog.setAfterEndDate(card.getEndDate());
            rideCardUserExtendLogDetailDao.insert(detailLog);
        }
        return Result.success();
    }

    @Override
    public Result<PageResult<RideCardUserExtendLog>> extendLogListPage(Page<RideCardUserExtendLog> pageOf, Integer accountId, String phone, Date startTime, Date endTime) {
        LambdaQueryWrapper<RideCardUserExtendLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RideCardUserExtendLog::getAccountId, accountId);
        if (StringUtils.isNotBlank(phone)) {
            queryWrapper.eq(RideCardUserExtendLog::getAccountUserPhone, phone);
        }
        if (Objects.nonNull(startTime) && Objects.nonNull(endTime)){
            queryWrapper.between(RideCardUserExtendLog::getCreateTime, startTime, endTime);
        }
        queryWrapper.orderByDesc(RideCardUserExtendLog::getCreateTime);
        IPage<RideCardUserExtendLog> page = rideCardUserExtendLogDao.selectPage(pageOf, queryWrapper);
        return Result.success(new PageResult<>((int) page.getCurrent(), (int) page.getSize(), page.getTotal(), (int) page.getPages(), page.getRecords()));
    }

    @Override
    public Result<PageResult<RideCardUserExtendLogDetail>> extendLogDetailListPage(Page<RideCardUserExtendLogDetail> pageOf, Integer logId, String phone) {
        LambdaQueryWrapper<RideCardUserExtendLogDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RideCardUserExtendLogDetail::getLogId, logId);
        if (StringUtils.isNotBlank(phone)) {
            queryWrapper.eq(RideCardUserExtendLogDetail::getUserPhone, phone);
        }
        IPage<RideCardUserExtendLogDetail> page = rideCardUserExtendLogDetailDao.selectPage(pageOf, queryWrapper);
        return Result.success(new PageResult<>((int) page.getCurrent(), (int) page.getSize(), page.getTotal(), (int) page.getPages(), page.getRecords()));
    }

    @Override
    public Result<String> modifyRideCardExpireTime(PackageDelayDTO delayDTO) {
        RideCardUser rideCardUser = rideCardDao.findRideCardUserByOrderNoAndUserId(delayDTO.getBusId(), delayDTO.getUserId());
        if (rideCardUser == null) {
            return Result.error("骑行套餐不存在");
        }
        RideCard rideCard = rideCardDao.getById(rideCardUser.getRideCardId());
        if (rideCard == null) {
            return Result.error("骑行套餐模板不存在");
        }
        if (rideCard.getUserType() == 0 && (rideCardUser.getUseCount() == null || rideCard.getMaxRide() - rideCardUser.getUseCount() <= 0)) {
            return Result.error("骑行套餐剩余次数为0,不能修改到期时间");
        }
        List<RefundLog> refundLogs = refundLogDao.selectList(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getMerchantNO, rideCardUser.getOrderNO()));
        if (CollectionUtils.isNotEmpty(refundLogs)) {
            return Result.error("骑行套餐已产生退款,不能修改到期时间");
        }
        Map<String, Object> queryMap = new HashMap<>(8);
        queryMap.put("accountId", rideCardUser.getAccountId());
        queryMap.put("userId", rideCardUser.getUserId());
        queryMap.put("valid", 1);
        queryMap.put("orderNoNotEq", rideCardUser.getOrderNO());
        Integer count = rideCardDao.countRideCardUserBy(queryMap);
        if (count > 0) {
            return Result.error("当前区域下已有生效的骑行套餐,不能修改到期时间");
        }
        rideCardUser.setEndDate(new Date(delayDTO.getDelayTime()));
        rideCardUser.setIsValid(true);
        rideCardDao.updateEndTimeByOrderNo(rideCardUser);
        return Result.success();
    }

    @Override
    public void updateCurrentNumByOrderNo(String orderNo, int updateCount) {
        rideCardDao.updateCurrentNumByOrderNo(orderNo, updateCount);
    }

    @Override
    public UserMember userRideCardByAccountIdList(Integer userId, List<Integer> accountIdList) {
        return rideCardDao.userRideCardByAccountIdList(userId, accountIdList);
    }

    @Override
    public int updateValid(UserMember userMember) {
        return rideCardDao.updateValid(userMember);
    }

    /**
     * 批量赠送骑行卡
     * @param file          文件
     * @param accountId     区域id
     * @param rideCardId    骑行卡id
     * @param remark        备注
     * @return              Result
     */
    @Override
    public Result<Object> batchGiveRideCard(MultipartFile file, Integer accountId, Integer rideCardId, String remark, LoginInfo login) {
        List<String> phoneList = readFileToPhone(file);
        if (CollectionUtils.isEmpty(phoneList)) {
            return Result.error("请输入手机号");
        }
        if (phoneList.size() > 1000) {
            return Result.error("添加用户过多，请不要超过1000");
        }
        if (remark.length() > 100) {
            return Result.error("备注过长，请重新输入");
        }

        //校验骑行卡
        RideCard rideCard = rideCardDao.getByAccountIdAndRideCardId(rideCardId, accountId);
        if (Objects.isNull(rideCard)){
            return Result.error("骑行卡不存在");
        }

        /*存在该品牌下的手机号*/
        List<User> userList = usersDao.selectByPhoneList(phoneList, accountDao.getBrandIdByAccountId(accountId, 3));

        if (CollectionUtils.isEmpty(userList)){
            return Result.error("用户不存在");
        }

        /*已有骑行卡且生效中的用户*/
        List<Integer> userIdList = userList.stream().map(User::getUserId).collect(Collectors.toList());
        List<Integer> hasRideCardUserId = rideCardDao.selectDoesNotExistRideCard(accountId, userIdList);

        List<Integer> noHasRideCardUserId = userIdList.stream().filter(userId -> !hasRideCardUserId.contains(userId)).collect(Collectors.toList());

        /*批量赠送骑行卡*/

        List<RideCardUser> rideCardUserList = new ArrayList<>();

        for (Integer userId : noHasRideCardUserId) {

            RideCardUser rideCardUser = new RideCardUser()
                    .setUserId(userId)
                    .setAccountId(accountId)
                    .setRideCardId(rideCardId)
                    .setBuyTime(new Date())
                    .setStartDate(new Date())
                    .setIsGive(1)
                    .setEndDate(DateTimeUtil.getRideCardEndDate(rideCard.getType(), rideCard.getVaildDays()))
                    .setOrderNO(UUID.randomUUID().toString().replace("-", ""))
                    .setPayState(1)
                    .setRemark(remark);

            rideCardUserList.add(rideCardUser);

        }

        if (CollectionUtils.isNotEmpty(rideCardUserList)){
            rideCardDao.batchInsertRideCardUser(rideCardUserList);
        }


        /*处理数据返回前端*/
        if (phoneList.size() != noHasRideCardUserId.size()){
            List<GiveRideCardVo> failList = new ArrayList<>();
            /*存在的手机号*/
            List<String> inDbPhone = userList.stream()
                    .map(User::getPhone)
                    .collect(Collectors.toList());

            /*筛选手机号不在数据库中*/
            phoneList.stream()
                    .filter(phone -> !inDbPhone.contains(phone))
                    .collect(Collectors.toList()).forEach(phone -> {
                        GiveRideCardVo giveRideCardVo = new GiveRideCardVo();
                        giveRideCardVo.setPhone(phone);
                        giveRideCardVo.setFailMsg("手机号不存在");
                        failList.add(giveRideCardVo);
                    });

            /*已存在骑行卡*/
            Map<Integer, String> map = userList.stream().collect(Collectors.toMap(User::getUserId, User::getPhone));
            hasRideCardUserId.stream()
                    .map(id -> {
                        GiveRideCardVo vo = new GiveRideCardVo();
                        vo.setPhone(map.get(id));
                        vo.setFailMsg("已有生效中骑行卡");
                        return vo;
                    })
                    .forEach(failList::add);

            return Result.success(failList);
        }


        return Result.success();
    }





    /**
     * 读取excel内容
     * @param file 文件
     * @return List<String>
     */
    private List<String> readFileToPhone(MultipartFile file){
        List<String> phoneList = new ArrayList<>();
        Workbook workbook;
        try {
            workbook = WorkbookFactory.create(Objects.requireNonNull(AdaPayUtil.MultipartFileToFile(file)));
            Sheet sheet = workbook.getSheetAt(0);
            Integer phoneIndex = null;
            boolean flag = true;
            for (Row row : sheet) {
                if (flag) {
                    //第一行为标题
                    Iterator<Cell> cellIterator = row.cellIterator();
                    while (cellIterator.hasNext()) {
                        Cell cell = cellIterator.next();
                        if ("手机号码".equals(cell.getStringCellValue())) {
                            phoneIndex = cell.getColumnIndex();
                        }
                    }
                    if (phoneIndex == null) {
                        throw new BaseException("excel文件数据有误");
                    }
                    flag = false;
                    continue;
                }
                //设置excel单元格类型
                row.getCell(phoneIndex).setCellType(CellType.STRING);
                String phone = row.getCell(phoneIndex).toString();
                if (StringUtils.isNotBlank(phone)){
                    phoneList.add(phone);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return phoneList;
    }





    private void updateHeadSort(Integer accountId) {
        rideCardDao.updateHeadSort(accountId);
    }

}
